﻿using Magicodes.Mvc.AuditFilter;
using Magicodes.Mvc.RoleMenuFilter;
using Magicodes.WeiChat.Data.Models;
using Magicodes.WeiChat.Data.Models.Interface;
using Magicodes.WeiChat.Infrastructure.MvcExtension.Ajax;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using Webdiyer.WebControls.Mvc;
using System.Data.Entity;

namespace Magicodes.WeiChat.Controllers
{
    public class CRUDBaseController<TEntry, TKey> : TenantBaseController<TEntry>
        where TEntry : WeiChat_TenantBase<TKey>, new()
    {
        // GET: Hospital_Notice
        protected ActionResult IndexView(string q, int pageIndex = 1, int pageSize = 10, Func<IQueryable<TEntry>, IQueryable<TEntry>> filterFunc = null, Func<IQueryable<TEntry>, IOrderedQueryable<TEntry>> orderFunc = null, Func<IQueryable<TEntry>, IQueryable<TEntry>> preFilterFunc = null)
        {
            var queryable = db.Set<TEntry>().Include(p => p.CreateUser).Include(p => p.UpdateUser).AsQueryable();
            if (preFilterFunc != null)
            {
                queryable = preFilterFunc(queryable);
            }
            if (!string.IsNullOrWhiteSpace(q) && filterFunc != null)
            {
                queryable = filterFunc(queryable);
            }
            var data = orderFunc != null ? orderFunc(queryable) : queryable.OrderBy(p => p.TenantId);
            var pagedList = new PagedList<TEntry>(
                             data.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(),
                             pageIndex, pageSize, queryable.Count());
            return View(pagedList);
        }

        public virtual ActionResult Details(TKey id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            var model = db.Set<TEntry>().Find(id);
            model.CreateUser = db.Users.Find(model.CreateBy);
            model.UpdateUser = db.Users.Find(model.UpdateBy);
            if (model == null)
            {
                return HttpNotFound();
            }
            return View(model);
        }
        public virtual ActionResult Create()
        {
            return View();
        }
        [HttpPost]
        [ValidateAntiForgeryToken]
        public virtual ActionResult Create(TEntry model)
        {
            return CreatePostView(model);
        }

        protected ActionResult CreatePostView(TEntry model, ActionResult result = null)
        {
            if (ModelState.IsValid)
            {
                model.CreateBy = UserId;
                model.CreateTime = DateTime.Now;
                model.TenantId = TenantId;
                db.Set<TEntry>().Add(model);
                db.SaveChanges();
                if (result != null) return result;
                return RedirectToAction("Index");
            }
            return View(model);
        }

        public virtual ActionResult Edit(TKey id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            var model = db.Set<TEntry>().Find(id);
            if (model == null)
            {
                return HttpNotFound();
            }
            return View(model);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public virtual ActionResult Edit(TEntry model)
        {
            return EditPostView(model);
        }

        protected ActionResult EditPostView(TEntry model, ActionResult result = null)
        {
            if (ModelState.IsValid)
            {
                db.Set<TEntry>().Attach(model);
                //取数据库值
                var databaseValues = db.Entry(model).GetDatabaseValues();
                model.CreateBy = databaseValues.GetValue<string>("CreateBy");
                model.CreateTime = databaseValues.GetValue<DateTime>("CreateTime");
                model.TenantId = databaseValues.GetValue<int>("TenantId");
                model.UpdateTime = DateTime.Now;
                model.UpdateBy = UserId;
                db.Entry(model).State = System.Data.Entity.EntityState.Modified;
                db.SaveChanges();
                if (result != null) return result;
                return RedirectToAction("Index");
            }
            return View(model);
        }


        public virtual ActionResult Delete(TKey id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            var model = db.Set<TEntry>().Find(id);
            model.CreateUser = db.Users.Find(model.CreateBy);
            model.UpdateUser = db.Users.Find(model.UpdateBy);
            if (model == null)
            {
                return HttpNotFound();
            }
            return View(model);
        }

        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public virtual ActionResult DeleteConfirmed(TKey id)
        {
            return DeleteConfirmedView(id);
        }

        protected ActionResult DeleteConfirmedView(TKey id, ActionResult result = null)
        {
            var model = db.Set<TEntry>().Find(id);
            db.Set<TEntry>().Remove(model);
            db.SaveChanges();
            return result == null ? RedirectToAction("Index") : result;
        }

        /// <summary>
        /// 批量操作
        /// </summary>
        /// <param name="operation">操作方法</param>
        /// <param name="ids">主键集合</param>
        /// <returns></returns>
        [HttpPost]
        [Route("BatchOperation/{operation}")]
        public virtual ActionResult BatchOperation(string operation, params TKey[] ids)
        {
            var ajaxResponse = new AjaxResponse();
            if (ids.Length > 0)
            {
                try
                {
                    var models = db.Set<TEntry>().Where(p => ids.Contains(p.Id)).ToList();
                    if (models.Count == 0)
                    {
                        ajaxResponse.Success = false;
                        ajaxResponse.Message = "没有找到匹配的项，项已被删除或不存在！";
                        return Json(ajaxResponse);
                    }
                    switch (operation.ToUpper())
                    {
                        case "DELETE":
                            #region 删除
                            {
                                db.Set<TEntry>().RemoveRange(models);
                                db.SaveChanges();
                                ajaxResponse.Success = true;
                                ajaxResponse.Message = string.Format("已成功操作{0}项！", models.Count);
                                break;
                            }
                        #endregion
                        default:
                            break;
                    }
                }
                catch (Exception ex)
                {
                    ajaxResponse.Success = false;
                    ajaxResponse.Message = ex.Message;
                }
            }
            else
            {
                ajaxResponse.Success = false;
                ajaxResponse.Message = "请至少选择一项！";
            }
            return Json(ajaxResponse);
        }
    }
}